﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;


namespace BusinessDll
{
    public class DBWeight
    {
        public static System.IO.Ports.SerialPort serialPort1 = new System.IO.Ports.SerialPort();
        public static string grossWeight;
        public static bool isDBRunning = true;
        public static Thread dbThread;
        public static int dbInterval = 500;
        public void init() {
            //todo
            Dictionary<string, string> wtParam = new Dictionary<string, string>();
            serialPort1.BaudRate = Int32.Parse(wtParam["BAUDRATE"]);
            serialPort1.PortName = wtParam["COMID"];
            serialPort1.DataBits = 8;
            serialPort1.StopBits = System.IO.Ports.StopBits.One;
            // 无奇偶校验位  
            serialPort1.Parity = System.IO.Ports.Parity.None;
            if (!serialPort1.IsOpen)
            {
                try
                {
                    serialPort1.Open();
                    WriteLog.showOnUI("地磅", "地磅连接成功");
                }
                catch (System.Exception ex)
                {
                    WriteLog.showOnUI("地磅", "地磅连接失败");
                }
            }
            else
            {
                WriteLog.showOnUI("地磅", "地磅已连接");
            }
            dbThread = new Thread(serialPort1_DataReceivedThread);
            dbThread.Priority = ThreadPriority.AboveNormal;
            dbThread.Start();
        }
        public void stop() {
            isDBRunning = false;
            if (serialPort1 != null) {
                serialPort1.Close();            
            }
        }
        public static void ReceiveDate()
        {
            if (serialPort1 != null && serialPort1.IsOpen)
            {
                int nRead = serialPort1.BytesToRead;
                if (nRead <= 0)
                {
                    WriteLog.WriteDebugLogs("采集", "没读取到数据");
                    return;
                }

                byte[] m_recvBytes = new byte[serialPort1.BytesToRead]; //定义缓冲区大小  
                int result = serialPort1.Read(m_recvBytes, 0, m_recvBytes.Length); //从串口读取数据  
                WriteLog.WriteDebugLogs("采集", "read length is " + nRead);
                string str = Encoding.UTF8.GetString(m_recvBytes, 0, m_recvBytes.Length); //对数据进行转换  
                serialPort1.DiscardInBuffer();
                string k = str.Substring(0, 1);
                if (k.Equals("="))
                {
                    WriteLog.WriteDebugLogs("采集", "=开头的重量是" + str);
                    str.Remove(0);
                    //return;
                }
                if (str.Equals("="))
                {
                    //错误的字串就直接返回哇。使用上一个正确的重量
                    WriteLog.WriteDebugLogs("采集", "空字符串=");
                    return;
                }
                if (str.Length < 5)
                {
                    //如果是无效的字串，那就直接选取上一次正确的值就好了。
                    WriteLog.WriteDebugLogs("采集", "过小的重量字符串是" + str);
                    return;

                }
                else
                {
                    grossWeight = "0";
                }
                try
                {
                    //沈轶文修改于20230606，地磅采集字符串解析

                    string[] arrStr = str.Split('=');
                    if (arrStr.Length < 4)
                    {
                        try
                        {
                            if (str[0] == '=')
                            {
                                string strWeight = getWeiStr(arrStr[1]);
                                grossWeight = strWeight;
                            }
                            else
                            {
                                string strWeight = getWeiStr(arrStr[0]);
                                grossWeight = strWeight;
                            }
                        }
                        catch (Exception ex)
                        {
                            WriteLog.WriteDebugLogs("采集", "出错的串为" + str);
                            WriteLog.printException(ex);
                        }
                    }
                    else
                    {
                        //等也可以
                        grossWeight = chgWeigthStr(arrStr[arrStr.Length - 2]);
                        try
                        {
                            if (Convert.ToInt32(grossWeight) < 20)
                            {
                                grossWeight = "0";
                                return;
                            }
                        }
                        catch (Exception ex)
                        {
                            WriteLog.WriteDebugLogs("地磅", "地磅重量错误解析:" + str);
                            WriteLog.printException(ex);
                        }
                    }

                }
                catch (System.Exception ex)
                {
                    WriteLog.WriteDebugLogs("地磅", "地磅重量错误str:" + str);
                    WriteLog.printException(ex);
                }
            }
            else
            {
                WriteLog.WriteDebugLogs("数据采集", "丢失地磅连接，请检查设备");
            }
        }
        private static string getWeiStr(string _strsrc)
        {
            string strRet = "";
            _strsrc = _strsrc.Trim();
            int nStart = _strsrc.IndexOf(".");
            int nEnd = _strsrc.Length - 1;
            nStart = nStart >= 0 ? nStart + 1 : 0;
            nEnd = nEnd > 0 ? nEnd : _strsrc.Length - 1;
            int length = nEnd - nStart;
            string strTmp = _strsrc.Substring(nStart, nEnd);
            for (int i = 0; i < length; i++)
            {
                strRet += strTmp[length - i - 1];
            }
            strRet = strRet.TrimStart('0');
            return strRet;
        }
        private static string chgWeigthStr(string strTmp)
        {
            string strRet = "0";
            for (int i = 0; i < strTmp.Length; i++)
            {
                if (!isNumber(strTmp[strTmp.Length - i - 1]))
                {
                    break;
                }
                strRet += strTmp[strTmp.Length - i - 1];
            }
            strRet = strRet.TrimStart('0');
            if (strRet.Length <= 0)
            {
                strRet = "0";
            }
            return strRet;
        }
        public static bool isNumber(char _src)
        {
            return _src <= 57 && _src >= 48;
        }

        private void serialPort1_DataReceived(object sender, System.IO.Ports.SerialDataReceivedEventArgs e)
        {
            Thread.Sleep(100);

        }
        //使用高优先级线程监听
        private static void serialPort1_DataReceivedThread()
        {

            while (isDBRunning)
            {
                try
                {
                    ReceiveDate();
                    Thread.Sleep(dbInterval);
                }
                catch (Exception ex)
                {
                    WriteLog.printException(ex);
                }
            }
        }
        public static void serialDataReceived()
        {

#if useShortFetch
            Boolean flag= true;
            do {
                ReceiveDate();
                if (!grossWeight.Equals("0") && !grossWeight.Equals(this.OLD_GrossWeight))
                {
                    //采集到，且和上一笔不等，则采取此结果
                         flag = false;
                         this.OLD_GrossWeight = grossWeight;
                 }
                //Thread.Sleep(100);
            } while(flag); 
#endif
            //author:沈轶文
            //写这个函数是读取逻辑。最终的取值给到GrossWeight
            Boolean bLoop = true;
            int retryTime = 0;
            int sum = 0;
            float avg = 0;
            //识别了多少个
            int num = 0;
            System.Collections.Generic.List<int> weightList = new System.Collections.Generic.List<int>();
            //int grossTmp = 0;
            int index = 5;
            BusinessControl.GrossWeight = grossWeight;
            while (index-- > 0)
            {
                try
                {
                    int grossTmp = 0;
                    if (grossWeight.Length <= 0) {
                        WriteLog.WriteLogs("采集", "没采集到数据");
                        continue;
                    } 
                    grossTmp = Convert.ToInt32(grossWeight);
#if invalidCheck
                    if (grossTmp < 60)
                    {
                        //重量过低则处理
                        if (retryTime > 5)
                        {
                            WriteLogs("重量采集", "没采集到重量，或者地磅问题"+grossTmp);
                            GrossWeight = grossWeight;
                            retryTime = 0;
                            return;
                            //break;
                        }
                        else
                        {
                            WriteLogs("重量采集", "没采集到重量，或者地磅问题。第" + retryTime + "次");
                            retryTime += 1;
                            //重采不占合法次数
                            index++;
                            Thread.Sleep(200);
                            continue;
                        }
                    }
#endif
                    sum += grossTmp;
                    weightList.Add(grossTmp);
                    WriteLog.WriteLogs("采集", "采集到的数据" + grossTmp);

                }
                catch (Exception ex)
                {
                    WriteLog.printException(ex);
                }

                //循环读取port里的数据
                Thread.Sleep(dbInterval);
            }
            //数据处理。不放在循环里，避免取值问题
            //avg = sum / weightList.Count;
            //求个中位数，成为重量。因为每次都用5个，所以我就不写偶数个了
            try
            {
                if (weightList == null || weightList.Count == 0)
                {
                    BusinessControl.GrossWeight = "0";
                }
                else
                {
                    int[] weightTmp = weightList.ToArray();
                    Array.Sort(weightTmp);
                    int med = 0; ;
                    int len = weightTmp.Length;
                    med = weightTmp[len / 2];
                    BusinessControl.GrossWeight = med.ToString();
                }
            }
            catch (Exception ex)
            {
                WriteLog.printException(ex);
            }
        }
    }
}
